/**
 * <copyright>
 * </copyright>
 *
 * $Id$
 */
package mS.impl;

import genArchi.AbstractTask;

import java.util.Collection;

import mS.CPU;
import mS.Data;
import mS.MSPackage;

import node1.impl.Node1Impl;

import org.eclipse.emf.common.notify.Notification;
import org.eclipse.emf.common.notify.NotificationChain;

import org.eclipse.emf.common.util.BasicEList;
import org.eclipse.emf.common.util.EList;

import org.eclipse.emf.ecore.EClass;
import org.eclipse.emf.ecore.InternalEObject;

import org.eclipse.emf.ecore.impl.ENotificationImpl;

import org.eclipse.emf.ecore.util.EObjectContainmentEList;
import org.eclipse.emf.ecore.util.InternalEList;

import utils.UtilsModelInstance;

import completeModel.SubTask;
import completeModel.Task;

/**
 * <!-- begin-user-doc -->
 * An implementation of the model object '<em><b>System</b></em>'.
 * <!-- end-user-doc -->
 * <p>
 * The following features are implemented:
 * <ul>
 *   <li>{@link mS.impl.SystemImpl#getId <em>Id</em>}</li>
 *   <li>{@link mS.impl.SystemImpl#getDatas <em>Datas</em>}</li>
 *   <li>{@link mS.impl.SystemImpl#getCpus <em>Cpus</em>}</li>
 * </ul>
 * </p>
 *
 * @generated
 */
public class SystemImpl extends Node1Impl implements mS.System {
	/**
	 * The default value of the '{@link #getId() <em>Id</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getId()
	 * @generated
	 * @ordered
	 */
	protected static final String ID_EDEFAULT = null;

	/**
	 * The cached value of the '{@link #getId() <em>Id</em>}' attribute.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getId()
	 * @generated
	 * @ordered
	 */
	protected String id = ID_EDEFAULT;

	/**
	 * The cached value of the '{@link #getDatas() <em>Datas</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getDatas()
	 * @generated
	 * @ordered
	 */
	protected EList<Data> datas;

	/**
	 * The cached value of the '{@link #getCpus() <em>Cpus</em>}' containment reference list.
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @see #getCpus()
	 * @generated
	 * @ordered
	 */
	protected EList<CPU> cpus;

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	protected SystemImpl() {
		super();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	protected EClass eStaticClass() {
		return MSPackage.Literals.SYSTEM;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public String getId() {
		return id;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public void setId(String newId) {
		String oldId = id;
		id = newId;
		if (eNotificationRequired())
			eNotify(new ENotificationImpl(this, Notification.SET, MSPackage.SYSTEM__ID, oldId, id));
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<Data> getDatas() {
		if (datas == null) {
			datas = new EObjectContainmentEList<Data>(Data.class, this, MSPackage.SYSTEM__DATAS);
		}
		return datas;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	public EList<CPU> getCpus() {
		if (cpus == null) {
			cpus = new EObjectContainmentEList<CPU>(CPU.class, this, MSPackage.SYSTEM__CPUS);
		}
		return cpus;
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public NotificationChain eInverseRemove(InternalEObject otherEnd, int featureID, NotificationChain msgs) {
		switch (featureID) {
			case MSPackage.SYSTEM__DATAS:
				return ((InternalEList<?>)getDatas()).basicRemove(otherEnd, msgs);
			case MSPackage.SYSTEM__CPUS:
				return ((InternalEList<?>)getCpus()).basicRemove(otherEnd, msgs);
		}
		return super.eInverseRemove(otherEnd, featureID, msgs);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public Object eGet(int featureID, boolean resolve, boolean coreType) {
		switch (featureID) {
			case MSPackage.SYSTEM__ID:
				return getId();
			case MSPackage.SYSTEM__DATAS:
				return getDatas();
			case MSPackage.SYSTEM__CPUS:
				return getCpus();
		}
		return super.eGet(featureID, resolve, coreType);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@SuppressWarnings("unchecked")
	@Override
	public void eSet(int featureID, Object newValue) {
		switch (featureID) {
			case MSPackage.SYSTEM__ID:
				setId((String)newValue);
				return;
			case MSPackage.SYSTEM__DATAS:
				getDatas().clear();
				getDatas().addAll((Collection<? extends Data>)newValue);
				return;
			case MSPackage.SYSTEM__CPUS:
				getCpus().clear();
				getCpus().addAll((Collection<? extends CPU>)newValue);
				return;
		}
		super.eSet(featureID, newValue);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public void eUnset(int featureID) {
		switch (featureID) {
			case MSPackage.SYSTEM__ID:
				setId(ID_EDEFAULT);
				return;
			case MSPackage.SYSTEM__DATAS:
				getDatas().clear();
				return;
			case MSPackage.SYSTEM__CPUS:
				getCpus().clear();
				return;
		}
		super.eUnset(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public boolean eIsSet(int featureID) {
		switch (featureID) {
			case MSPackage.SYSTEM__ID:
				return ID_EDEFAULT == null ? id != null : !ID_EDEFAULT.equals(id);
			case MSPackage.SYSTEM__DATAS:
				return datas != null && !datas.isEmpty();
			case MSPackage.SYSTEM__CPUS:
				return cpus != null && !cpus.isEmpty();
		}
		return super.eIsSet(featureID);
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated
	 */
	@Override
	public String toString() {
		if (eIsProxy()) return super.toString();

		StringBuffer result = new StringBuffer(super.toString());
		result.append(" (id: ");
		result.append(id);
		result.append(')');
		return result.toString();
	}

	/**
	 * <!-- begin-user-doc -->
	 * <!-- end-user-doc -->
	 * @generated NOT
	 */
	public void compute() {
		
		boolean equalsPeriod = true;
		
		/**/
		EList<Integer> l_period = new BasicEList<Integer> ();
		EList<Integer> l_wcet = new BasicEList<Integer> ();
		EList<Integer> l_deadline = new BasicEList<Integer> ();
		EList<Integer> l_priority = new BasicEList<Integer> ();
		EList<String> l_name = new BasicEList<String> ();
		
		
		/**/
		for (AbstractTask at : this.tasks) {
			
			Task t = (Task)at;
			
			/**/
			for (SubTask st : t.getSubTasks()) {
				
				l_name.add(st.getSubId());
				l_period.add(t.getPeriod());
				l_deadline.add(t.getDeadline());
				
				if (t.getDeadline() < t.getPeriod()) {
					
					equalsPeriod = false;
				}
				
				l_wcet.add(st.getWcet());
				l_priority.add(st.getPriority());
			}

		}
		
		if (equalsPeriod) {
			
			/* Create Models with specific assumptions, then add to general List and children list*/
			BasicModelType1 lm_1 = (BasicModelType1)UtilsModelInstance.createBasicModelType1(this.getCpus().get(0).getPolicy(), l_name, l_wcet, l_period, l_priority);
			UtilsModelInstance.linkComputeBox(this, lm_1, false);
			lm_1.compute();
		}
		
		/* Create Model type 2, deadline less or equal than period with specific assumptions, then add to general List and children list*/
		BasicModelType2 lm_2 = (BasicModelType2)UtilsModelInstance.createBasicModelType2( this.getCpus().get(0).getPolicy(), l_name, l_wcet, l_period, l_deadline, l_priority);
		UtilsModelInstance.linkComputeBox(this, lm_2, false);
		lm_2.compute();
		
	}

} //SystemImpl
